// $codepro.audit.disable numericLiterals
/**
 * package for all the model classes to fit the mvc format
 */
package javamonsters.model;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.swing.JOptionPane;

/**
 * Class representing the Ship Yard
 * 
 * @author Evan
 * @version 1.0
 */
public class ShipYard implements java.io.Serializable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -1629123897023548266L;
	
	/**
	 * object output stream
	 */
	private ObjectOutputStream out;

	/**
	 * Map of buyable ships
	 */
	private final Map<Ship, ShipItem> shipMap;
	
	/**
	 * List of buyable ships
	 */
	private final List<Ship> shipList;
	
	/**
	 * The parent planet of the ship yard
	 */
	private final Planet planet;
	
	/**
	 * the player that is in the ship yard
	 */
	private Character player;
	
	/**
	 * maxCapacity of buyable ship list (7, b/c there are only 7 possible ships)
	 */
	private final int maxCapacity;
	
	/**
	 * ShipYard constructor
	 * @param planet the parent planet of the ship yard
	 */
	public ShipYard(Planet planet) {
		maxCapacity = 7;
		this.planet = planet;
		this.shipList = new ArrayList<Ship>();
		for (int i = 0; i < Ship.ShipType.values().length; i++) {
			shipList.add(new Ship(Ship.ShipType.values()[i]));
		}
		this.shipMap = new HashMap<Ship, ShipItem>(maxCapacity);
		for (Ship ship : shipList) {
			shipMap.put(ship, new ShipItem(new BigDecimal(ship.getPrice())));
		}
		
	}
	
	/**
	 * @return String representation of ship yard
	 */
	public String toString() {
		return "ship yard";
	}
	
	/**
	 * method that buys ship for player and changes his/her credits appropriately
	 * 
	 * @param ship the ship to be bought
	 */
	public void buyShip(Ship ship) {
		if (player.getCredits().compareTo(new BigDecimal(ship.getPrice())) >= 0) {
			
		    final Map<TradeGood, InventoryItem> oldCargo = 
		    		planet.getMarketplace().getSellMap();
		    
			BigDecimal refundValue = new BigDecimal(0);
			
			for (Entry<TradeGood, InventoryItem> entry : oldCargo.entrySet()) {
				
				Integer quantity = entry.getValue().getQuantity();
				
				refundValue = refundValue.add(entry.getValue()
			    .getPrice().multiply(new BigDecimal(quantity)));
			}
			
			player.setShip(ship);
			
			BigDecimal prevCredits = player.getCredits();
			prevCredits = prevCredits.subtract(new BigDecimal(ship.getPrice()));
			prevCredits = prevCredits.add(refundValue);
		
			player.setCredits(prevCredits);
			
			final String message1 = "You just purchased a new ship! " +
					                "While all of your cargo " +
							        "was taken, you received ";
			
			final String message2 = " credits due to the worth of your cargo.";
			
			JOptionPane.showMessageDialog(null, message1 + refundValue + message2);
			
		}
	}
	
	/**
	 * @return the map of buyable ships
	 */
	public Map<Ship, ShipItem> getShipMap() {
		return shipMap;
	}
	
	/**
	 * Setter for the ship yards current character
	 * 
	 * @param p the player to be set
	 */
	public void setCurrentCharacter(Player p) {
		this.player = p;
	}
	
	/**
	 * @return the ship yards current character
	 */
	public Character getCurrentCharacter() {
		return player;
	}
	
	/**
	 * writes this object to a save file
	 * 
	 * @param filename the name of the file to be written to
	 * @throws IOException
	 */
	public void writeObject(String filename) throws IOException {
		try {
			out = new ObjectOutputStream(new FileOutputStream(filename + ".dat"));
			out.writeObject(this);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			out.close();
		}
	}

}
